package caidan.net;

import jinyilw.common.app.AppConfig;
import jinyilw.common.file.FileTools;
import jinyilw.swing.visuals.window.HintWindow;
import jinyilw.tools.h2db.DBConfig;
import jinyilw.tools.net.ClientTools;
import jinyilw.tools.net.dev.CommandPacket;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

public class SuggestPanel extends AbstractSuggestPanel
{
	private static final long serialVersionUID = -8424692830726670977L;
	private static final File suggestFile = new File(FileTools.createDirectory(
			AppConfig.getAppDataFolder(), "clientData"), "suggest");
	private final ArrayList<SuggestLabel> localLabels;
	private final ClientTools clientTools;

	public SuggestPanel(ClientTools tools)
	{
		clientTools = tools;
		localLabels = new ArrayList<SuggestLabel>();
	}

	@Override
	public void initNet()
	{
		jdbcTools = DBConfig.getDefaultTools();
		isConnected = jdbcTools.isConnected();
		clientTools.bindJdbcTools(jdbcTools);
		clientTools.addReceivePacketOperator((Object o) ->
		{
			if (o instanceof CommandPacket)
			{
				CommandPacket packet = (CommandPacket) o;
				if (Command.freshSuggest == packet.getCommandID())
					new Thread(() ->
					{
						reloadDatabase();
					}).start();
			}
		});

		reloadDatabase();
		jdbcTools.addReConnectRunner(() ->
		{
			reloadDatabase();
		});
		jdbcTools.addBrokenRunner(() ->
		{
			isConnected = false;
			for (SuggestLabel label : suggestLabels)
				label.updateTitle();
		});
	}
	private boolean isFristOpen = true;
	@Override
	public synchronized void reloadDatabase()
	{
		isConnected = jdbcTools.isConnected();
		if (!isConnected && !isFristOpen)
			return;
		contentPanel.removeAll();
		readFromDatabase();
		if (isFristOpen)
		{
			initFromFile();
			isFristOpen = false;
		}
		for (SuggestLabel label : suggestLabels)
			contentPanel.add(label);
		for (SuggestLabel label : localLabels)
			contentPanel.add(label);
		revalidate();
		repaint();
	}

	void initFromFile()
	{
		if (suggestFile == null || !suggestFile.isFile())
			return;
		DataInputStream dis = null;
		boolean isNet, isSend;
		String user, content, dateString;
		Suggest suggest;
		SuggestLabel label;
		try
		{
			dis = new DataInputStream(new FileInputStream(suggestFile));
			int length = dis.readInt();
			for (int j = 0; j < length; j++)
			{
				isNet = dis.readBoolean();
				isSend = dis.readBoolean();
				user = dis.readUTF();
				content = dis.readUTF();
				dateString = dis.readUTF();
				if (isConnected && isNet)
					continue;
				suggest = new Suggest(user, content, dateString);
				label = new SuggestLabel(suggest, isNet, isSend);
				// contentPanel.add(label);
				if (isNet)
					suggestLabels.add(label);
				else
					localLabels.add(label);
			}
			dis.close();
		} catch (Exception e)
		{
			e.printStackTrace();
			try
			{
				if (dis != null)
					dis.close();
			} catch (IOException e1)
			{
				e1.printStackTrace();
			}
		}
	}

	public void writeToFile()
	{
		DataOutputStream dos = null;
		try
		{
			dos = new DataOutputStream(new FileOutputStream(suggestFile));
			dos.writeInt(suggestLabels.size() + localLabels.size());
			for (SuggestLabel label : suggestLabels)
				label.writeData(dos);
			for (SuggestLabel label : localLabels)
				label.writeData(dos);
			dos.close();
		} catch (Exception e)
		{
			e.printStackTrace();
			try
			{
				if (dos != null)
					dos.close();
			} catch (IOException e1)
			{
				e1.printStackTrace();
			}
		}
	}

	@Override
	public void removeSuggestLabel(SuggestLabel label)
	{
		contentPanel.remove(label);
		revalidate();
		repaint();
		if (label.isNet)
			suggestLabels.remove(label);
		else
			localLabels.remove(label);
	}

	@Override
	public void addSuggestLabel(SuggestLabel label)
	{
		contentPanel.add(label);
		revalidate();
		repaint();

		if (label.isNet)
			suggestLabels.add(label);
		else
			localLabels.add(label);
	}

	public boolean sendSuggestToNet(Suggest suggest)
	{
		String sql = "insert into adminSuggest(user,content,dateString) values(?,?,?)";
		boolean ok = jdbcTools.updateByPreparedStatement(sql, suggest.getUser(),
				suggest.getContent(), suggest.getDateString());
		if (ok)
			sendCommand(new CommandPacket(Command.freshSuggest, true));
		return ok;
	}

	public void sendCommand(CommandPacket commandPacket)
	{
		clientTools.sendCommand(commandPacket);
	}

	@Override
	public boolean isClient()
	{
		return true;
	}

	@Override
	public void sendSuggest(SuggestLabel suggestLabel)
	{
		if (sendSuggestToNet(suggestLabel.suggest))
		{
			suggestLabel.isSend = true;
			suggestLabel.sendComp.setEnabled(false);
			HintWindow.showHint("已发送到网络！", getParent());
			suggestLabel.sendComp.setToolTipText("已发送");
		} else
			HintWindow.showHint("发送失败！", getParent());
	}
}
